package com.zrf.geekbang.spring.bean;

import com.zrf.geekbang.spring.ioc.overview.container.AnnotationApplicationContextAsIocContainerDemo;
import com.zrf.geekbang.spring.ioc.overview.domain.User;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.Map;

/**
 * @author zhouruifeng
 * @date 2020-06-21
 */
@Import(AnnotationBeanDefinitionDemo.Config.class)//通过@Import
public class AnnotationBeanDefinitionDemo {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        //注入配置类
        applicationContext.register(Config.class);
        /**
         * 1. 通过@Bean方式定义
         * 2. 通过@Component方式定义
         * 3. 通过@Import方式通过导入
         */
        //通过beanDefinition API
        beanDefinition(applicationContext, "zrf111User",User.class);
        //通过非命名方式
        beanDefinition(applicationContext, User.class);

        //启动应用上下文
        applicationContext.refresh();

        Map<String, User> beansOfType = applicationContext.getBeansOfType(User.class);
        System.out.println(beansOfType);


        //显示关闭上下文
        applicationContext.close();
    }

    public static void beanDefinition(BeanDefinitionRegistry beanDefinitionRegistry, String beanName, Class<?> cls) {
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(cls);
        beanDefinitionBuilder.addPropertyValue("id", 111111L);
        beanDefinitionBuilder.addPropertyValue("name", AnnotationApplicationContextAsIocContainerDemo.class.toString());

        if (StringUtils.hasText(beanName)) {
            beanDefinitionRegistry.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
        } else {
            //非命名方式
            BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinitionBuilder.getBeanDefinition(), beanDefinitionRegistry);
        }
    }

    public static void beanDefinition(BeanDefinitionRegistry beanDefinitionRegistry, Class<?> cls) {
        beanDefinition(beanDefinitionRegistry, null, cls);
    }

    @Component//通过@Component
    public static class Config {
        /**
         * 通过注解的方式定义bean
         *
         * @return
         */
        @Bean({"user", "zrfUser"})
        public User zrfUser() {
            User user = new User();
            user.setId(111111L);
            user.setName(this.getClass().getName());
            return user;
        }
    }

}
